﻿using System;
using System.Collections.Generic;
using System.Globalization;
using Xenta.Enums;

namespace Xenta.Entities
{
    /// <summary>
    /// Represents the dimensional specification entity.
    /// </summary>
    /// <remarks><pre>
    /// The entity regarding the disclosure level.
    /// 
    /// + Entire
    ///  + Extended
    ///   | - Weight
    ///   | - Width
    ///   | - Length
    ///   | - Height
    ///   + Base
    ///    | - Code
    ///    | - Item(of the Primary level)
    ///    | - SKU
    ///    | - CommonFlags
    ///    | - UpdatedOn
    ///    | - CreatedOn
    ///    + Keys
    ///     + Primary
    ///      | - EntityID
    /// 
    /// Note: upper level includes lower level.
    /// </pre></remarks>
    public class CatalogItemDimensionalSpecEntity : CatalogItemSpecEntity
    {
        #region Constants

        /// <summary>
        /// The specification system code.
        /// </summary>
        public const string CODE = "DIMENSION";

        #endregion

        #region Properties

        /// <summary>
        /// Gets the specification system code.
        /// </summary>
        public override string Code
        {
            get
            {
                return CODE;
            }
        }

        /// <summary>
        /// Gets or sets the weight.
        /// </summary>
        public virtual decimal Weight
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the length.
        /// </summary>
        public virtual decimal Length
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the width.
        /// </summary>
        public virtual decimal Width
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the height.
        /// </summary>
        public virtual decimal Height
        {
            get;
            set;
        }

        #endregion

        #region Methods

        /// <summary>
        /// Converts the specification to the key-value pair collection.
        /// </summary>
        /// <returns>The key-value pair collection.</returns>
        public override IDictionary<String, String> ToDictionary()
        {
            return new Dictionary<String, String>
            {
                {"Weight", Weight.ToString("F2", CultureInfo.InvariantCulture)},
                {"Length", Length.ToString("F2", CultureInfo.InvariantCulture)},
                {"Width", Width.ToString("F2", CultureInfo.InvariantCulture)},
                {"Height", Height.ToString("F2", CultureInfo.InvariantCulture)}
            };
        }

        #endregion

        #region Utils

        protected override void Disclose(IDictionary<String, Object> obj,
            DisclosureLevel level,
            IDictionary<String, String> options)
        {
            base.Disclose(obj, level, options);
            if(level >= DisclosureLevel.Extended)
            {
                obj["Weight"] = Weight;
                obj["Width"] = Width;
                obj["Length"] = Length;
                obj["Height"] = Height;
            }
        }

        #endregion
    }

    /// <summary>
    /// The entity NHibernate mapping.
    /// </summary>
    public class CatalogItemDimensionalSpecMapping : JoinedEntityMapping<CatalogItemDimensionalSpecEntity>
    {
        /// <summary>
        /// Initializes a new class instance.
        /// </summary>
        public CatalogItemDimensionalSpecMapping()
        {
            Table("fwk_CatalogItemDimensionalSpecifications");
            Key(m =>
            {
                m.NotNullable(true);
                m.Column("DimensionalSpecificationID");
                m.ForeignKey("FK_fwk_CatalogItemDimensionalSpecifications_fwk_CatalogItemSpecifications");
            });
            Property(x => x.Weight, m =>
            {
                m.Precision(19);
                m.Scale(4);
                m.NotNullable(true);
            });
            Property(x => x.Length, m =>
            {
                m.Precision(19);
                m.Scale(4);
                m.NotNullable(true);
            });
            Property(x => x.Width, m =>
            {
                m.Precision(19);
                m.Scale(4);
                m.NotNullable(true);
            });
            Property(x => x.Height, m =>
            {
                m.Precision(19);
                m.Scale(4);
                m.NotNullable(true);
            });
        }
    }
}
